home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / util / moni / Scout-src.lha / source / scout_net.c < prev    next >
C/C++ Source or Header  |  2002-09-16  |  20KB  |  717 lines

  1. /**
  2.  * Scout - The Amiga System Monitor
  3.  *
  4.  *------------------------------------------------------------------
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * You must not use this source code to gain profit of any kind!
  21.  *
  22.  *------------------------------------------------------------------
  23.  *
  24.  * @author Andreas Gelhausen
  25.  * @author Richard Körber <rkoerber@gmx.de>
  26.  */
  27.  
  28. #include "system_headers.h"
  29.  
  30. extern APTR    AP_Scout;
  31. extern STRPTR  _ProgramName;
  32.  
  33. /********************************************************************/
  34. /*                      Benötigte Prototypes                        */
  35. /********************************************************************/
  36.  
  37. #define NAMELEN      32
  38. #define LINELEN      82
  39. #define TRENNCHAR    '\0'
  40.  
  41. UBYTE *CMD_BEGIN = "BEGIN";
  42. UBYTE *CMD_USER = "USER";
  43. UBYTE *CMD_PASSWORD = "PASSWORD";
  44. UBYTE *CMD_END = "END";
  45. UBYTE *CMD_DONE = "DONE";
  46. UBYTE *CMD_ERROR = "ERROR";
  47. UBYTE *CMD_CONNECTED = "CONNECTED";
  48.  
  49. static struct RDArgs *rdargs;
  50. static struct RDArgs *myrdargs;
  51.  
  52. static int server_socket = -1;
  53. static int client_socket = -1;
  54. static int connected = FALSE;
  55. static long type = SOCK_STREAM;
  56.  
  57. static long sinlen;
  58. static struct sockaddr_in sin;
  59.  
  60. BOOL clientstate = FALSE;
  61. BOOL serverstate = FALSE;
  62. BOOL shellstate = FALSE;
  63.  
  64. char username[10+1];
  65. char password[_PASSWORD_LEN+1];
  66.  
  67. void failtcp( void )
  68. {
  69.     if (client_socket >= 0) {
  70.         if (connected) shutdown(client_socket, 2);
  71.         CloseSocket(client_socket);
  72.     }
  73.  
  74.     if (UserGroupBase) CloseLibrary(UserGroupBase);
  75.  
  76.     if (SocketBase) CloseLibrary(SocketBase);
  77. }
  78.  
  79. int inittcp( void )
  80. {
  81.     if (!(SocketBase = OpenLibrary("bsdsocket.library", 4L))) return FALSE;
  82.     if (!(UserGroupBase = OpenLibrary("usergroup.library", 4))) return FALSE;
  83.  
  84.     return TRUE;
  85. }
  86.  
  87. static int sgetc( int sock )
  88. {
  89.     unsigned char c;
  90.     fd_set rd,ex;
  91.     ULONG flgs;
  92.     int n;
  93.     struct timeval t;
  94.  
  95.     t.tv_sec = 10L;
  96.     t.tv_usec = 0;
  97.  
  98.     FD_ZERO(&rd);
  99.     FD_ZERO(&ex);
  100.  
  101.     FD_SET(sock,&rd);
  102.     FD_SET(sock,&ex);
  103.  
  104.     if (clientstate) {
  105.         flgs = 0;
  106.         WaitSelect(16,&rd,0L,&ex,&t,&flgs);
  107.     } else {
  108.         flgs = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D;
  109.         WaitSelect(16,&rd,0L,&ex,NULL,&flgs);
  110.     }
  111.  
  112.     if (FD_ISSET(sock,&rd)) {
  113.         n = recv(sock, &c, 1, 0);
  114.         if (n == 1) {
  115.             return c;
  116.         } else {
  117.             return -1;
  118.         }
  119.     } else {
  120.         return -1;
  121.     }
  122. }
  123.  
  124. int sgets( int sock,
  125.            char *string,
  126.            int maxchars )
  127. {
  128.     int nchars = 0;
  129.     char c;
  130.  
  131.     while (nchars < maxchars && (c = sgetc(sock)) != EOF && c != TRENNCHAR) {
  132.         string[nchars] = c;
  133.         nchars++;
  134.     }
  135.     string[nchars] = '\0';
  136.     return nchars;
  137. }
  138.  
  139. static char NetHelpText[] = "\n" \
  140.     " Available lists:\n" \
  141.     " ----------------\n" \
  142.     " Allocations     Assigns         BoopsiClasses   Commands\n" \
  143.     " Commodities     Devices         Expansions      Fonts\n" \
  144.     " InputHandlers   Interrupts      Libraries       Locks\n" \
  145.     " LowMemory       Memory          Mounts          Ports\n" \
  146.     " Residents       Resources       ScreenMode      Semaphores\n" \
  147.     " System          Tasks           Timer           Vectors\n" \
  148.     " Windows\n\n" \
  149.     " Other commands:\n" \
  150.     " ---------------\n" \
  151.     " Help";
  152.  
  153. void PrintNetHelp( void )
  154. {
  155.     if (serverstate || shellstate) {
  156.         int i = 0;
  157.         UBYTE *tmp;
  158.  
  159.         if (tmp = AllocVec(256, MEMF_ANY)) {
  160.             SendResultString(NetHelpText);
  161.  
  162.             while (arexx_list[i].mc_Name) {
  163.                strcpy(tmp, " ");
  164.                strcat(tmp, arexx_list[i].mc_Name);
  165.                if (arexx_list[i].mc_Parameters) {
  166.                    strcat (tmp, " ");
  167.                    strcat (tmp, arexx_list[i].mc_Template);
  168.                }
  169.                SendResultString(tmp);
  170.                i++;
  171.             }
  172.  
  173.             FreeVec(tmp);
  174.         }
  175.     }
  176. }
  177.  
  178. /*
  179. ** Dieser Hook wird benötigt um die ARexx-Command-Liste für
  180. **  die TCP_Befehle nutzen zu können!
  181. */
  182. struct NetHook {
  183.    struct   MinNode  h_egal1;
  184.    __asm    ULONG    (*h_Entry) (register __a1 ULONG *);
  185.    ULONG    (*h_egal2)();
  186.    APTR     h_egal3;
  187. };
  188.  
  189. struct Net_Command {
  190.     char *nc_Name;
  191.     void (*nc_func)(char *);
  192. };
  193.  
  194. struct Net_Command net_list[] = {
  195.     "Allocations",         PrintAllocations,
  196.     "Assigns",             PrintAssigns,
  197.     "BoopsiClasses",       PrintClass,
  198.     "Commands",            PrintCommands,
  199.     "Commodities",         PrintCx,
  200.     "Devices",             PrintDevices,
  201.     "Expansions",          PrintExpansions,
  202.     "Fonts",               PrintFonts,
  203.     "InputHandlers",       PrintInputHandlers,
  204.     "Interrupts",          PrintInterrupts,
  205.     "Libraries",           PrintLibraries,
  206.     "LowMemory",           PrintLowMemory,
  207.     "Memory",              PrintMemory,
  208.     "Mounts",              PrintMounts,
  209.     "Locks",               PrintLocks,
  210.     "Ports",               PrintPorts,
  211.     "Residents",           PrintResidents,
  212.     "ScreenMode",          PrintSMode,
  213.     "Semaphores",          PrintSemaphores,
  214.     "System",              PrintSystem,
  215.     "Tasks",               PrintTasks,
  216.     "Timer",               PrintTimer,
  217.     "Resources",           PrintResources,
  218.     "Vectors",             PrintVectors,
  219.     "Windows",             PrintWindows,
  220.     "Patches",             PrintPatches,
  221.     "Catalogs",            PrintCatalogs,
  222.     "AudioModes",          PrintAudioModes,
  223.     "ResetHandlers",       PrintResetHandlers,
  224.     "Help",                (void (* ) (char *)) PrintNetHelp,
  225.     "a",                   PrintAllocations,
  226.     "b",                   PrintClass,
  227.     "c",                   PrintCommands,
  228.     "d",                   PrintDevices,
  229.     "e",                   PrintTimer,
  230.     "f",                   PrintFonts,
  231.     "g",                   PrintAssigns,
  232.     "h",                   PrintInputHandlers,
  233.     "i",                   PrintInterrupts,
  234.     "j",                   PrintLowMemory,
  235.     "k",                   PrintCx,
  236.     "l",                   PrintLibraries,
  237.     "m",                   PrintMemory,
  238.     "n",                   PrintMounts,
  239.     "o",                   PrintLocks,
  240.     "p",                   PrintPorts,
  241.     "r",                   PrintResidents,
  242.     "s",                   PrintSemaphores,
  243.     "t",                   PrintTasks,
  244.     "u",                   PrintResources,
  245.     "v",                   PrintVectors,
  246.     "w",                   PrintWindows,
  247.     "x",                   PrintExpansions,
  248.     "y",                   PrintSystem,
  249.     "z",                   PrintSMode,
  250.     "GetAlcList",          (void (* ) (char *))SendAlcList,
  251.     "GetAssList",          (void (* ) (char *))SendAssList,
  252.     "GetClassList",        (void (* ) (char *))SendClassList,
  253.     "GetComList",          (void (* ) (char *))SendComList,
  254.     "GetCxList",           (void (* ) (char *))SendCxList,
  255.     "GetDevList",          (void (* ) (char *))SendDevList,
  256.     "GetExpList",          (void (* ) (char *))SendExpList,
  257.     "GetFontList",         (void (* ) (char *))SendFontList,
  258.     "GetInputList",        (void (* ) (char *))SendInputList,
  259.     "GetIntList",          (void (* ) (char *))SendIntList,
  260.     "GetLibList",          (void (* ) (char *))SendLibList,
  261.     "GetLockList",         (void (* ) (char *))SendLockList,
  262.     "GetLowMemList",       (void (* ) (char *))SendLowMemory,
  263.     "GetMemList",          (void (* ) (char *))SendMemList,
  264.     "GetMountList",        (void (* ) (char *))SendMountList,
  265.     "GetPortList",         (void (* ) (char *))SendPortList,
  266.     "GetResList",          (void (* ) (char *))SendResList,
  267.     "GetResiList",         (void (* ) (char *))SendResiList,
  268.     "GetSemList",          (void (* ) (char *))SendSemList,
  269.     "GetSModeList",        (void (* ) (char *))SendSModeList,
  270.     "GetSysList",          (void (* ) (char *))SendSystemList,
  271.     "GetTaskList",         (void (* ) (char *))SendTaskList,
  272.     "GetTimerList",        (void (* ) (char *))SendTimerList,
  273.     "GetVectorList",       (void (* ) (char *))SendVectorList,
  274.     "GetWinList",          (void (* ) (char *))SendWinList,
  275.     "GetPatchList",        (void (* ) (char *))SendPatchList,
  276.     "GetCatalogList",      (void (* ) (char *))SendCatalogList,
  277.     "GetAudioModeList",    (void (* ) (char *))SendAudioModeList,
  278.     "GetResetHandlerList", (void (* ) (char *))SendResetHandlersList,
  279.     NULL
  280. };
  281.  
  282. /********************************************************************/
  283. /*                              Client                              */
  284. /********************************************************************/
  285.  
  286. int SendDaemon( UBYTE *fmt, ... )
  287. {
  288.     int result = FALSE;
  289.     UBYTE *buf;
  290.  
  291.     if (buf = tbAllocVecPooled(globalPool, LINELEN)) {
  292.         va_list args;
  293.  
  294.         va_start(args,fmt);
  295.         _vsnprintf(buf, LINELEN, fmt, args);
  296.         va_end (args);
  297.  
  298.         if (send(client_socket, buf, strlen(buf) + 1, 0) == strlen(buf) + 1) {
  299.             result = TRUE;
  300.         }
  301.  
  302.         tbFreeVecPooled(globalPool, buf);
  303.     }
  304.  
  305.     return result;
  306. }
  307.  
  308. static ULONG NetCommand( UBYTE *text )
  309. {
  310.     ULONG rc = RETURN_FAIL;
  311.     UBYTE *buf;
  312.  
  313.     if (buf = tbAllocVecPooled(globalPool, LINELEN)) {
  314.         if (send(client_socket, text, strlen(text) + 1, 0) == strlen(text) + 1) {
  315.             while (sgets(client_socket, buf, LINELEN)) {
  316.                 if (strcmp(buf, CMD_DONE) == 0) {
  317.                     rc = RETURN_OK;
  318.                     break;
  319.                 } else if (strcmp(buf, CMD_ERROR) == 0) {
  320.                     break;
  321.                 }
  322.             }
  323.         }
  324.  
  325.         tbFreeVecPooled(globalPool, buf);
  326.     }
  327.  
  328.     return rc;
  329. }
  330.  
  331. BOOL ReceiveDecodedEntry( UBYTE *structure,
  332.                           ULONG length )
  333. {
  334.     BOOL rc = FALSE;
  335.  
  336.     if (sgets(client_socket, structure, length)) {
  337.         if (strcmp(structure, CMD_ERROR) != 0 && strcmp(structure, CMD_DONE) != 0) {
  338.             ULONG i = 0;
  339.  
  340.             while (i < length - 1) {
  341.                 if (structure[i] == '\1') structure[i] = '\0';
  342.                 i++;
  343.             }
  344.  
  345.             rc = TRUE;
  346.         }
  347.     }
  348.  
  349.     return rc;
  350. }
  351.  
  352. int ConnectToServer( void )
  353. {
  354.    UBYTE hostname[NAMELEN];
  355.    UBYTE buffer[LINELEN+2];
  356.    struct hostent *host;
  357.    struct sockaddr_in server;
  358.  
  359.    if (!inittcp()) {
  360.        aprintf(msgCantInitTCPIP);
  361.        return FALSE;
  362.    }
  363.  
  364.    if (opts.User) {
  365.        stccpy(username, opts.User, sizeof(username));
  366.    } else {
  367.        stccpy(username, getlogin(), sizeof(username));
  368.    }
  369.  
  370.    if (opts.Password) {
  371.        stccpy(password, opts.Password, sizeof(password));
  372.    } else {
  373.        stccpy(password, getpass(msgAskForPassword), sizeof(password));
  374.        if (password[0] == '\0') {
  375.            aprintf(msgCantGetPassword);
  376.            return FALSE;
  377.        }
  378.    }
  379.  
  380.    gethostname(hostname, sizeof(hostname));
  381.  
  382.    if (host = gethostbyname(opts.Host)) {
  383.        bzero((char *)&server, sizeof(server));
  384.        server.sin_port = 6543;
  385.        bcopy(host->h_addr, (char *)&server.sin_addr, host->h_length);
  386.        server.sin_family = host->h_addrtype;
  387.  
  388.        client_socket = socket(AF_INET, type, 0);
  389.        if (client_socket >= 0) {
  390.            if (connect (client_socket, (struct sockaddr *) &server, sizeof (server)) != -1) {
  391.                connected = TRUE;
  392.                if (SendDaemon(CMD_BEGIN)) {
  393.                    if (SendDaemon("%s %s", CMD_USER, username) && SendDaemon("%s %s", CMD_PASSWORD, password)) {
  394.                        if (sgets(client_socket, buffer, LINELEN) && strcmp(buffer, CMD_CONNECTED) != 0) {
  395.                           aprintf(buffer);
  396.                       } else {
  397.                           return TRUE;
  398.                       }
  399.                    }
  400.                }
  401.            } else {
  402.               aprintf(msgCantConnectToServer);
  403.            }
  404.        } else {
  405.            aprintf(msgCantCreateSocket);
  406.        }
  407.    } else {
  408.        aprintf(msgCantFindHost, opts.Host);
  409.    }
  410.    return FALSE;
  411. }
  412.  
  413. ULONG netshellclient( void )
  414. {
  415.     ULONG rc = RETURN_FAIL;
  416.     UBYTE recvbuffer[LINELEN+2];
  417.  
  418.     if (clientstate = ConnectToServer()) {
  419.         if (SendDaemon("%s ", opts.Command)) {
  420.             while (sgets(client_socket, recvbuffer, LINELEN) && strcmp(recvbuffer, CMD_ERROR) != 0 && strcmp(recvbuffer, CMD_DONE) != 0) {
  421.                aprintf(recvbuffer);
  422.             }
  423.             if (strcmp(recvbuffer, CMD_DONE) == 0) {
  424.                 rc = RETURN_OK;
  425.             } else {
  426.                 rc = RETURN_ERROR;
  427.             }
  428.             SendDaemon(CMD_END);
  429.         }
  430.     }
  431.  
  432.     return rc;
  433. }
  434.  
  435. /********************************************************************/
  436. /*                              Daemon                              */
  437. /********************************************************************/
  438.  
  439. int isNetCall (void) {
  440.    int   rc = TRUE;
  441.  
  442.    if (! inittcp()) {
  443.       return (FALSE);
  444.    }
  445.  
  446.    server_socket = init_inet_daemon();
  447.    if (server_socket >= 0) {
  448.       set_socket_stdio (server_socket);
  449.       sinlen = sizeof (sin);
  450.       if (getpeername (0, (struct sockaddr *) &sin, &sinlen) == -1) {
  451. //         logprint ("scout: getpeername() failed\n");
  452.          rc = FALSE;
  453.       }
  454.    } else {
  455. //      logprint ("scout: init_inet_daemon() failed\n");
  456.       rc = FALSE;
  457.    }
  458.    return (rc);
  459. }
  460.  
  461. int isCommand (char *buffer, char *command) {
  462.    int len = strlen (command);
  463.    int rc = FALSE;
  464.  
  465.    if ((strnicmp (buffer, command, len) == 0) \
  466.      && ((isspace (buffer[len])) || (buffer[len] == '\0'))) {
  467.       rc = len + 1;
  468.    }
  469.    return (rc);
  470. }
  471.  
  472. int SendClient (char *fmt, ...)
  473. {
  474.     int   result = FALSE;
  475.     UBYTE *buf;
  476.  
  477.     if (buf = tbAllocVecPooled(globalPool, TMP_STRING_LENGTH)) {
  478.         va_list args;
  479.  
  480.         va_start(args,fmt);
  481.         _vsnprintf(buf, TMP_STRING_LENGTH, fmt, args);
  482.  
  483.         if (send(0, buf, strlen(buf) + 1, 0) == strlen(buf) + 1) {
  484.             result = TRUE;
  485.         }
  486.  
  487.         va_end(args);
  488.  
  489.         tbFreeVecPooled(globalPool, buf);
  490.     }
  491.  
  492.     return result;
  493. }
  494.  
  495. BOOL SendEncodedEntry( UBYTE *structure, ULONG length )
  496. {
  497.     ULONG i = 0;
  498.  
  499.     while (i < length - 1) {
  500.         if (structure[i] == '\0') structure[i] = '\1';
  501.         i++;
  502.     }
  503.  
  504.     if (SendClient(structure)) {
  505.         return FALSE;
  506.     }
  507.  
  508.     return TRUE;
  509. }
  510.  
  511. long SendResultString( UBYTE *fmt, ... )
  512. {
  513.    UBYTE *buf;
  514.  
  515.    if (buf = tbAllocVecPooled(globalPool, TMP_STRING_LENGTH)) {
  516.        va_list args;
  517.  
  518.        va_start(args, fmt);
  519.        _vsnprintf(buf, TMP_STRING_LENGTH, fmt, args);
  520.  
  521.        if (serverstate) {
  522.            strcat(buf, "\n");
  523.            SendClient(buf);
  524.        } else if (shellstate) {
  525.            strcat(buf, "\n");
  526.            Printf(buf);
  527.        } else {
  528.            set(AP_Scout, MUIA_Application_RexxString, buf);
  529.        }
  530.  
  531.        va_end (args);
  532.  
  533.        tbFreeVecPooled(globalPool, buf);
  534.     }
  535.  
  536.     return (TRUE);
  537. }
  538.  
  539. void PrintFOneLine( BPTR hd,
  540.                     UBYTE *fmt, ... )
  541. {
  542.     UBYTE *buf;
  543.  
  544.     if (buf = tbAllocVecPooled(globalPool, TMP_STRING_LENGTH)) {
  545.         va_list args;
  546.  
  547.         va_start(args, fmt);
  548.         _vsnprintf(buf, TMP_STRING_LENGTH, fmt, args);
  549.         va_end(args);
  550.  
  551.         if (serverstate) {
  552.             SendClient(buf);
  553.         } else {
  554.             Write(hd, buf, strlen(buf));
  555.         }
  556.  
  557.         tbFreeVecPooled(globalPool, buf);
  558.     }
  559. }
  560.  
  561. ULONG ExecuteCommand (char *text) {
  562.    ULONG    rc = RETURN_OK;
  563.    char     buffer[256];
  564.    int      i, len;
  565.  
  566.    #define  CMDOPT_TEMPLATE "CMD1/A"
  567.    #define  CMDOPT_COUNT    4
  568.    LONG     cmdopts[CMDOPT_COUNT];
  569.  
  570.    _snprintf(buffer, sizeof(buffer), "%s ", text);
  571.  
  572.    i = 0;
  573.    while (arexx_list[i].mc_Name) {
  574.       if (len = isCommand (buffer, arexx_list[i].mc_Name)) {
  575.  
  576.          if (myrdargs = AllocDosObject (DOS_RDARGS,NULL)) {
  577.             myrdargs->RDA_Source.CS_Buffer = buffer + len;
  578.             myrdargs->RDA_Source.CS_Length = strlen (buffer) - len;
  579.  
  580.             if ((arexx_list[i].mc_Parameters && (rdargs = ReadArgs (arexx_list[i].mc_Template, (LONG *) &cmdopts, myrdargs))) \
  581.               || (!arexx_list[i].mc_Parameters)) {
  582.  
  583.                rc = (*((struct NetHook *) arexx_list[i].mc_Hook)->h_Entry) ((ULONG *) &cmdopts[0]);
  584.                FreeArgs (rdargs);
  585.             } else {
  586.  
  587.                Fault (IoErr(), NULL, (char *) buffer, LINELEN);
  588.                SendResultString (buffer);
  589.                rc = RETURN_FAIL;
  590.             }
  591.             FreeDosObject (DOS_RDARGS,myrdargs);
  592.          }
  593.          break;
  594.       }
  595.       i++;
  596.    }
  597.  
  598.    if (! (arexx_list[i].mc_Name)) {
  599.       i = 0;
  600.       while (net_list[i].nc_Name) {
  601.          if (len = isCommand (buffer, net_list[i].nc_Name)) {
  602.  
  603.             if (myrdargs = AllocDosObject (DOS_RDARGS,NULL)) {
  604.                myrdargs->RDA_Source.CS_Buffer = buffer;
  605.                myrdargs->RDA_Source.CS_Length = strlen (buffer);
  606.  
  607.                if (rdargs = ReadArgs (CMDOPT_TEMPLATE, (LONG *) &cmdopts, myrdargs)) {
  608.  
  609.                   (*net_list[i].nc_func) (NULL);
  610.                   FreeArgs (rdargs);
  611.                } else {
  612.  
  613.                   Fault (IoErr(), NULL, (char *) buffer, LINELEN);
  614.                   SendResultString (buffer);
  615.                   rc = RETURN_FAIL;
  616.                }
  617.                FreeDosObject (DOS_RDARGS,myrdargs);
  618.             }
  619.             break;
  620.          }
  621.          i++;
  622.       }
  623.       if (! (net_list[i].nc_Name)) {
  624.          SendResultString(msgUnknownOption);
  625.          rc = RETURN_FAIL;
  626.       }
  627.    }
  628.    return (rc);
  629. }
  630.  
  631. ULONG netdaemon (VOID) {
  632.    ULONG    rc = TRUE;
  633.    char     buffer[LINELEN+2];
  634.    int      len, done = FALSE;
  635.  
  636.    struct   passwd   *pw, *rootpw;
  637.    long     rootid = 0;
  638.  
  639. /*
  640. ** inittcp() wurde bereits durch isNetCall() aufgerufen!
  641. */
  642.  
  643.    serverstate = TRUE;
  644.  
  645.    if (rootpw = getpwnam ("root"))
  646.       rootid = rootpw->pw_gid;
  647.  
  648.    if ((sgets (0, buffer, LINELEN)) && (strcmp (buffer, CMD_BEGIN) == 0)) {
  649. //logprint ("BEGIN\n");
  650.       if ((sgets (0, buffer, LINELEN)) && (len = isCommand (buffer, CMD_USER)) \
  651.         && (pw = getpwnam (buffer + len))) {
  652. //logprint ("USER %s\n", buffer + len);
  653.  
  654.          if (((rootpw) && (rootid == pw->pw_gid)) || (! rootpw)) {
  655.  
  656.             if ((sgets (0, buffer, LINELEN)) && (len = isCommand (buffer, CMD_PASSWORD))
  657.               && (strcmp (crypt (buffer + len, pw->pw_passwd), pw->pw_passwd) == 0)) {
  658. //logprint ("PASSWORD %s\n", buffer + len);
  659.  
  660.                if (SendClient (CMD_CONNECTED)) {
  661. //logprint ("'CONNECTED' send!\n");
  662.                   while (sgets (0, buffer, LINELEN)) {
  663. //logprint ("COMMAND '%s'\n", buffer);
  664.                      if (strcmp (buffer, CMD_END) == 0) {
  665.                         break;
  666.                      }
  667.  
  668.                      if (ExecuteCommand (buffer)) {
  669.                         SendClient (CMD_ERROR);
  670.                      } else {
  671.                         SendClient (CMD_DONE);
  672.                      }
  673.                      done = TRUE;
  674.                   }
  675.                }
  676.             } else {
  677.                SendClient(msgWrongPassword);
  678.             }
  679.          } else {
  680.             SendClient(msgNoPrivilege);
  681.          }
  682.       } else {
  683.          SendClient(msgUnknownUser);
  684.       }
  685.    } else {
  686.       SendClient(msgNoBEGINReceived);
  687.    }
  688.    if (! done)
  689.       SendClient (CMD_ERROR);
  690.  
  691.    serverstate = FALSE;
  692.    return (rc);
  693. }
  694.  
  695. int MyDoCommand (char *fmt, ...) {
  696.    int   result = FALSE;
  697.    char  buf[LINELEN];
  698.  
  699.    va_list args;
  700.    va_start(args,fmt);
  701.    _vsnprintf(buf, LINELEN, fmt, args);
  702.  
  703.    if (clientstate) {
  704.       if (! NetCommand (buf))
  705.          result = TRUE;
  706.    } else {
  707.       if (! ExecuteCommand (buf))
  708.          result = TRUE;
  709.    }
  710.    if (! result) {
  711.       MyRequest (msgErrorContinue, msgErrorOccured);
  712.    }
  713.    va_end (args);
  714.    return (result);
  715. }
  716.  
  717.